//==============================================================================
//	File:		$RCSfile: CounterExample.rdl,v $
//	Version:	$Revision: 1.8 $
//	Desc:		RDL Counter Example
//	Author:		Greg Gibeling
//	Copyright:	Copyright 2005-2007 UC Berkeley
//
//	This copyright header must appear in all derivative works
//==============================================================================

//==============================================================================
//	Section:	License
//==============================================================================
// Copyright (c) 2005-2007, Regents of the University of California
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//     - Redistributions of source code must retain the above copyright notice,
//         this list of conditions and the following disclaimer. 
//     - Redistributions in binary form must reproduce the above copyright
//         notice, this list of conditions and the following disclaimer
//         in the documentation and/or other materials provided with the
//         distribution. 
//     - Neither the name of the University of California, Berkeley nor the
//         names of its contributors may be used to endorse or promote
//         products derived from this software without specific prior
//         written permission. 
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//==============================================================================

//==============================================================================
//	Section:	CVS Change Log
//==============================================================================
//	$Log: CounterExample.rdl,v $
//	Revision 1.8  2007/03/24 22:45:19  sshd_server
//	Fixed capitalization to enable unit tests on case sensitive file systems
//	
//	Revision 1.7  2007/03/24 19:46:51  sshd_server
//	Added short comment about static identifiers at bottom
//	
//	Revision 1.6  2007/03/24 15:44:19  sshd_server
//	Implemented DualRegisterLink
//	Updated examples documentation slightly
//	Including diagrams in CVS & release
//	
//	Revision 1.5  2007/03/22 22:43:13  sshd_server
//	Implemented ISE project generator plugin
//	
//	Revision 1.4  2007/03/22 21:59:34  sshd_server
//	Implemented SynplifyPro project generator plugin
//	Testing is incomplete
//	
//	Revision 1.3  2007/03/22 11:59:32  sshd_server
//	Beefed up plugin comments
//	
//	Revision 1.2  2007/02/27 02:16:15  sshd_server
//	Updated copyright dates
//	
//	Revision 1.1  2007/02/26 19:19:36  sshd_server
//	Fixed unit tests to work with import of RDLC2 into RCF
//	Separated examples and test code in RDLC2
//	Closed workspace
//	
//	Revision 1.4  2006/04/21 02:24:33  sshd_server
//	Added support for all hardware platforms
//	CounterExample works again!
//	
//	Revision 1.3  2006/04/19 18:38:54  sshd_server
//	Fully implemented ModelSim CounterExample
//	
//	Revision 1.2  2006/04/19 02:01:15  sshd_server
//	Added modelsim platform
//	
//	Revision 1.1  2006/04/18 16:09:01  sshd_server
//	Implemented register links
//	Cleaned up copies of the counter example code
//	
//==============================================================================

//------------------------------------------------------------------------------
//	Unit:	CounterExample
//	Desc:	This is the top level unit of the design, as may be noted by it's
//			lack of input and output ports.  This unit instantiates the other
//			three and connects them together.
//			See the BooleanInput and DisplayNum units for a description of
//			plugins.
//------------------------------------------------------------------------------
unit <width> {
	plugin		Platforms::ModelSim	"SetParam"<$width, 32>	ModelSimWidth;
	plugin		Platforms::XUP		"SetParam"<$width, 4>	XUPWidth;
	plugin		Platforms::CaLinx2	"SetParam"<$width, 32>	CaLinx2Width;
	plugin		Platforms::S3		"SetParam"<$width, 16>	S3Width;

	instance	IO::BooleanInput				BooleanInputX(Value(InChannel));
	instance	Counter<$width>					CounterX(InChannel, OutChannel);
	instance	IO::DisplayNum<$width>			DisplayNumX;

	channel										InChannel;
	channel										OutChannel { -> DisplayNumX.Value };
}												CounterExample;
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//	Unit:		Counter
//	Desc:		The core of this example is this simple counter unit. Designed
//				as an up/down counter which is enabled by the receipt of a
//				message at it's UpDown port, this counter in response to the
//				input counts and sends the new value out on it's Count port.
//------------------------------------------------------------------------------
unit <width = 32, saturate = 1> {
	input		bit<1>							UpDown;
	output		bit<$width>						Count;
}												Counter;
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//	Namespace:	IO
//	Desc:		This is used both as an example of an RDL namespace and to
//				separate the IO units from the core units declared above.  In
//				normal practice this namespace might be included from another
//				file.  Notice that the name of the namespace is given on the
//				first line of the declaration, rather than the last, as for
//				units.
//------------------------------------------------------------------------------
namespace {
	//--------------------------------------------------------------------------
	//	Unit:	BooleanInput
	//	Desc:	This is a simple unit which produces messages in response to
	//			the push of a button.  The value of these messages is decided by
	//			a switch.
	//--------------------------------------------------------------------------
	unit <SwitchLoc, ButtonLoc, Invert> {
		output		bit<1>						Value;
		
		// These statements invoke the "Include" plugin which simply copies a source file (first
		// argument) to the given destination (second argument).  Since no destination is given
		// in these statements, the source file is copied to the root of the output tree.
		// Note that these plugins will only run if the platform this unit is mapped to uses the
		// "Verilog" language.
		plugin	"Verilog"	"Include"<"ButtonParse.v">	IncludeButtonParse;
		plugin	"Verilog"	"Include"<"Debouncer.v">	IncludeDebouncer;
		plugin	"Verilog"	"Include"<"EdgeDetect.v">	IncludeEdgeDetect;
		
		// These statements create the switch and button IO wires which are used by this unit to
		// determine the value and timing of it's output messages respectively, when the platform
		// this unit is mapped to uses the "Verilog" language.  Notice that the pin locations are
		// parameters, specified below through the "SetParam" plugin.
		// The "External" plugin takes argument: direction, width, directive0, value0, directive1,
		// value1, ..., directiven, valuen.  The direction can be "Input", "Output" or
		// "InOut", the width must be an integer, and the directives can be any XST synthesis
		// directive ("loc" and "iostandard" in particular).  This plugin will automatically
		// generate synthesis directives for both XST and Synplify Pro.  The plugin also
		// supports the "invert" directive, which is used by RDLC to control the external
		// inversion of the signal (before it enters the unit).
		plugin	"Verilog"	"External"<"Input", 1, "loc", $SwitchLoc, "invert", $Invert>	_SW;
		plugin	"Verilog"	"External"<"Input", 1, "loc", $ButtonLoc, "invert", $Invert>	_BTN;
		
		// These statements invoke the "SetParam" plugin which will set it's two arguments equal.
		// This can be used (as it is here) to provide platform specific parameters, when used
		// in conjunction with the restriction of the plugin to a certain platform (XUP, S3 and
		// CaLinx2) below.  This is essentially a "switch(platform) { case ...: ... }" wherein
		// we set the actual BGA balls that the external pins should be connected to.
		plugin	::1::Platforms::XUP "SetParam"<$SwitchLoc, "AC11">		SwitchXUP;	// SW7-0	(User Input 0, Right most dipswitch)
		plugin	::1::Platforms::XUP "SetParam"<$ButtonLoc, "AG5">		ButtonXUP;	// SW2		(ENTER, Center button)
		
		plugin	::1::Platforms::S3 "SetParam"<$SwitchLoc, "K13">		SwitchS3;	// SW7		(Left most switch)
		plugin	::1::Platforms::S3 "SetParam"<$ButtonLoc, "M13">		ButtonS3;	// BTN0		(Right most button)
		plugin	::1::Platforms::S3 "SetParam"<$Invert, true>			InvertS3;	// On the S3 board all the inputs are inverted
		
		plugin	::1::Platforms::CaLinx2 "SetParam"<$SwitchLoc, "AR37">	SwitchCaLinx2;	// SW10-8	(Bottom Dipswitch)
		plugin	::1::Platforms::CaLinx2 "SetParam"<$ButtonLoc, "AE39">	ButtonCaLinx2;	// SW3		(Upper right button)
		
		// Note that "SetParam" will silently fail if it's first argument already
		// has a value, meaning that this line will the "$Invert" to "false" only if it
		// wasnt already set.
		plugin	"SetParam"<$Invert, false>								InvertDefault;
	}											BooleanInput;
	//--------------------------------------------------------------------------

	//--------------------------------------------------------------------------
	//	Unit:	DisplayNum
	//	Desc:	This unit has been designed to output a number of arbitrary
	//			bitwidth on whatever platform it is on.  It currently supports the
	//			CaLinx2, XUP and Digilent S3 boards.
	//			See BooleanInput for more complete plugin documentation.
	//--------------------------------------------------------------------------
	unit <width = 32> {
		input		bit<$width>					Value;
		
		// These statements invoke the "Include" plugin which simply copies a source file to the
		// given destination.  Since no destination is given in these statements, the source file
		// is merely copied to the output directory.
		plugin	"Verilog"	"Include"<"Bin2HexLED.v">				IncludeBin2HexLED;
		plugin	"Verilog"	"Include"<"QuadHexLEDMux.v">			IncludeQuadHexLEDMux;
		plugin	"Verilog"	"Include"<"Register.v">					IncludeRegister;
		
		// These are the myriad of external connections for the 7 segment LEDs on the CaLinx2 board.
		plugin	::1::Platforms::CaLinx2	"External"<"Output", 7, "loc", "AV8,AW8,AU8,AT8,AV9,AU9,AT9">			SEG1;
		plugin	::1::Platforms::CaLinx2	"External"<"Output", 7, "loc", "AU10,AV10,AT10,AW11,AU11,AT11,AW12">	SEG2;
		plugin	::1::Platforms::CaLinx2	"External"<"Output", 7, "loc", "AT18,AR18,AU18,AV18,AR17,AT17,AU17">	SEG3;
		plugin	::1::Platforms::CaLinx2	"External"<"Output", 7, "loc", "AU21,AT19,AT21,AV20,AV21,AW21,AR22">	SEG4;
		plugin	::1::Platforms::CaLinx2	"External"<"Output", 7, "loc", "AW28,AT29,AV28,AU28,AV27,AU27,AT27">	SEG5;
		plugin	::1::Platforms::CaLinx2	"External"<"Output", 7, "loc", "AT31,AU31,AW30,AV30,AT30,AW29,AV29">	SEG6;
		plugin	::1::Platforms::CaLinx2	"External"<"Output", 7, "loc", "AU33,AV33,AT33,AW32,AU32,AT32,AW31">	SEG7;
		plugin	::1::Platforms::CaLinx2	"External"<"Output", 7, "loc", "AU36,AV36,AW35,AV35,AV34,AU34,AT34">	SEG8;
		plugin	::1::Platforms::CaLinx2	"External"<"Output", 8, "loc", "AW36,AW33,AV31,AU29,AU19,AV19,AW10,AT7">SEG_POINT;
		plugin	::1::Platforms::CaLinx2	"External"<"Output", 8, "loc", "AW34,AV32,AU30,AW27,AW20,AW18,AV11,AW9">SEG_COM_;
		
		// The four 7 segment LEDs on the Digilent S3 board are time multiplexed.
		plugin	::1::Platforms::S3	"External"<"Output", 8, "loc", "E14,G13,N15,P15,R16,F13,N16,P16">			SEG_;
		plugin	::1::Platforms::S3	"External"<"Output", 4, "loc", "E13,F14,G14,D14">							SEG_ANODE_;
		
		// The XUP board has only 4 single bit LEDs.
		plugin	::1::Platforms::XUP "External"<"Output", 4, "loc", "AA5,AA6,AC3,AC4">							LED;
	}											DisplayNum;
	//--------------------------------------------------------------------------
}												IO;
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//	Namespace:		Platforms
//	Desc:			This namespace holds the various platforms for which the
//					the counter example code has been implemented and tested.
//------------------------------------------------------------------------------
namespace {
	//--------------------------------------------------------------------------
	//	Platform:	Verilog
	//	Desc:		This platform will simply generate the relevant verilog code
	//				without an engine.  This is useful if you do not wish to
	//				actually run a design.
	//--------------------------------------------------------------------------
	platform {
		language 								"Verilog";
	}											Verilog;
	//--------------------------------------------------------------------------
	
	//--------------------------------------------------------------------------
	//	Platform:	ModelSim
	//	Desc:		This platform represents ModelSim SE.  It will cause the
	//				appropriate test bench code to be generated and, if
	//				possible, it will launch ModelSim and run a simulation.
	//--------------------------------------------------------------------------
	platform {
		language 								"Verilog";
		plugin	"ModelSimEngine"				Engine;			// Use the ModelSim engine plugin to generate the engine
		plugin	"ModuleLibrary"<"ModuleLibrary.xml"> Library;	// Use the standard verilog module library.
		plugin	"ModelSim"						Launch;			// Launch ModelSim (assuming vsim is on your path)
	}											ModelSim;
	//--------------------------------------------------------------------------
	
	//--------------------------------------------------------------------------
	//	Platform:	XUP
	//	Desc:		This is the platform for the Xilinx University Program FPGA
	//				board with the XC2VP30 on it.
	//--------------------------------------------------------------------------
	platform {
		language 								"Verilog";
		
		// The two lines below set the default link generator which should be
		// used on this platform.  Notice that they are both commented out because
		// the "Verilog" language back end will use the "RegisterLink" by
		// default.  Feel free to experiment with uncommenting one or the other.
		//plugin "RegisterLink" DefaultLink;		// The simplest link, a full/empty register with 1 cycle forwards and backwards latency
													// (no channel timing parameters are supported).  Notice that this will result in a
													// channel with 50% duty cycle (empty, full, empty, full, empty, ...).
		//plugin "DualRegisterLink" DefaultLink;	// Two full/empty registers with 1 cycle forwards and backwards latency (no channel
													// timing parameters are supported).  This will result in a channel which can have
													// 100% duty cycle, as a write and read can take place one the same cycle.  The cost
													// is double the number of register bits as in "RegisterLink", hence the name!
		
		// Use the Virtex2 Pro engine plugin.  Note that for the XUP board the
		// clock is pin AJ15, and uses the LVCMOS25 standard.  Synthesis attributes
		// can be added using XST style names.  The generated code will work
		// with both XST and Synplify Pro!
		plugin	"Virtex2ProEngine"<"AJ15", "iostandard", "LVCMOS25"> Engine;
		
		plugin	"ModuleLibrary"<"ModuleLibrary.xml"> Library;
		
		// The below line would invoke SynplifyPro to do the compilation, and then
		// drive the back end PAR tools, if it were uncommented.  To experiment
		// with this, make sure to comment out the below line with "XFlow" in it.
		// THIS PLUGIN HAS NOT BEEN TESTED, PLEASE REPORT ANY PROBLEMS!
		//plugin "SynplifyPro"<"synplifypro\XUP.prj", true>	Compile;
		
		// This plugin will generate an ISE project for the mapping to this platform.
		// This plugin invocation is NOT REQUIRED, as XFlow and Impact do not rely on
		// it.  It could be commented to no effect, and is included for you education
		// only.
		plugin "ISE"<"virtex2p", "xc2vp30", "-7", "ff896", "Modelsim">	ISEProject;
		
		// These two plugins will cause XFlow to be used to compile the resulting
		// verilog files, and Impact to be invoked to program the chip, either using
		// a ParallelIV cable or the XUP's USB programmer.
		plugin	"XFlow"<"-p", "xc2vp30-6ff896", "-synth", "xst_verilog.opt", "-implement", "balanced.opt", "-config", "bitgen.opt"> Compile;
		plugin	"Impact"<"setMode -bs", "setCable -p auto", "identify", "assignFile -p 3", "program -p 3"> Impact;
	}											XUP;
	//--------------------------------------------------------------------------
	
	//--------------------------------------------------------------------------
	//	Platform:	CaLinx2
	//	Desc:		This is the platform description for the UC Berkeley CaLinx2
	//				board.  For more information on the board please see
	//				http://calinx.eecs.berkeley.edu/
	//--------------------------------------------------------------------------
	platform {
		language 								"Verilog";
		plugin	"VirtexEEngine"<"A20">			Engine;
		plugin	"ModuleLibrary"<"ModuleLibrary.xml"> Library;
		plugin "ISE"<"virtexe", "xcv2000e", "-6", "fg680", "Modelsim">	ISEProject;
		plugin	"XFlow"<"-p", "xcv2000e-6fg680", "-synth", "xst_verilog.opt", "-implement", "balanced.opt", "-config", "bitgen.opt"> Compile;
		plugin	"Impact"<"setMode -bs", "setCable -p auto", "identify", "assignFile -p 2", "program -p 2"> Impact;
	}											CaLinx2;
	//--------------------------------------------------------------------------
	
	//--------------------------------------------------------------------------
	//	Platform:	S3
	//	Desc:		This platform description is for the DigilentInc Spartan3
	//				board.  For more information on the board please see
	//				http://www.digilentinc.com/
	//--------------------------------------------------------------------------
	platform {
		language 								"Verilog";
		plugin	"Spartan3Engine"<"T9">			Engine;
		plugin	"ModuleLibrary"<"ModuleLibrary.xml"> Library;
		plugin "ISE"<"spartan3", "xc3s200", "-4", "ft256", "Modelsim">	ISEProject;
		plugin	"XFlow"<"-p", "xc3s200-4ft256", "-synth", "xst_verilog.opt", "-implement", "balanced.opt", "-config", "bitgen.opt"> Compile;
		plugin	"Impact"<"setMode -bs", "setCable -p auto", "identify", "assignFile -p 1", "program -p 1"> Impact;
	}											S3;
	//--------------------------------------------------------------------------
}												Platforms;
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//	Namespace:		Maps
//	Desc:			This namespace holds the various mappings of the counter
//					example to the various platforms specified in the
//					::Platforms namespace.
//------------------------------------------------------------------------------
namespace {
	//--------------------------------------------------------------------------
	//	Map:		Verilog
	//	Desc:		This will generate basic verilog output.
	//--------------------------------------------------------------------------
	map {
		// The syntax "::1::CounterExample" means, go up one level in the
		// namespace hierarchy and look for a declaration named "CounterExample".
		// "::2::Dummy" would mean go up two levels and look for "Dummy".
		// "::Dummy" would mean go to the root of the namespaces and look for
		// "Dummy".
		unit		::1::CounterExample				Unit;
		platform	::1::Platforms::Verilog			Platform;
	}												Verilog;
	//--------------------------------------------------------------------------

	//--------------------------------------------------------------------------
	//	Map:		ModelSim
	//	Desc:		Maps the counter example to ModelSim SE.
	//--------------------------------------------------------------------------
	map {
		unit		::1::CounterExample				Unit;
		platform	::1::Platforms::ModelSim		Platform;
	}												ModelSim;
	//--------------------------------------------------------------------------
	
	//--------------------------------------------------------------------------
	//	Map:		XUP
	//	Desc:		Maps the counter example to the XUP FPGA board.
	//--------------------------------------------------------------------------
	map {
		unit		::1::CounterExample				Unit;
		platform	::1::Platforms::XUP				Platform;
	}												XUP;
	//--------------------------------------------------------------------------
	
	//--------------------------------------------------------------------------
	//	Map:		CaLinx2
	//	Desc:		Maps the counter example to the CaLinx2 FPGA board.
	//--------------------------------------------------------------------------
	map {
		unit		::1::CounterExample				Unit;
		platform	::1::Platforms::CaLinx2			Platform;
	}												CaLinx2;
	//--------------------------------------------------------------------------
	
	//--------------------------------------------------------------------------
	//	Map:		S3
	//	Desc:		Maps the counter example to the Digilent S3 FPGA board.
	//--------------------------------------------------------------------------
	map {
		unit		::1::CounterExample				Unit;
		platform	::1::Platforms::S3				Platform;
	}												S3;
	//--------------------------------------------------------------------------
}													Maps;
//------------------------------------------------------------------------------